home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * mac_via.c, adapted from VIA_TIMER.c.
- *
- * Copyright (c) 1991 Symantec Corporation. All rights reserved.
- *
- */
-
- #include <LIBlib.h>
-
- // From <LoMem.h>: Warning: can't be used on a Power Mac.
- // #include <LoMem.h>
-
- #include <Memory.h>
-
- #define Declare_LoMem(type, name, address) type (name) : (address)
- Declare_LoMem(THz, ApplZone, 0x2AA);
- Declare_LoMem(Ptr, VIA, 0x1D4);
- #ifdef THINK_C
- ProcPtr Lvl1DT[] : 0x192;
- ProcPtr Lvl2DT[] : 0x1B2;
- #endif
-
- #include <Memory.h> /* VIA */
- #include <stdlib.h>
- #include <profile.h>
-
- #define vT1C (512*4)
- #define vT1CH (512*5)
- #define vIER (512*14)
-
- struct words { short hi, lo; };
- struct bytes { char hi, lo; };
-
- /* tick count */
- static union {
- long dword;
- struct words word;
- } elapsed;
-
- /* VIA countdown timer #1 */
- static union {
- short word;
- struct bytes byte;
- } timer;
-
- static struct {
- ProcPtr vector;
- char enable;
- } save;
-
- static Boolean timer_running, exithook_installed;
-
-
- /*
- * VIA_ticks - return tick count
- *
- * Each tick represents approximately 1.28 micro-seconds.
- *
- */
- void my_start_VIA_timer(int flag);
-
- long
- VIA_ticks()
- {
- long entry_dword = elapsed.dword;
-
- if (!timer_running)
- my_start_VIA_timer(FALSE);
-
- /* Wait for the high byte of the countdown timer to change. */
- do {
- timer.byte.hi = VIA[vT1CH];
- timer.byte.lo = VIA[vT1C];
- } while (timer.byte.hi != VIA[vT1CH]);
-
- /* This sets only the low part. The high part is set by the rollover. */
- elapsed.word.lo = ~timer.word;
-
- #if 0 /* new code: doesn't seem to work at all. */
- if (elapsed.dword < entry_dword) {
- es("VIA_TICKS: adjusting...");
- #if 0
- es("VIA[vIER]: "); ehex(VIA[vIER] & 0xff);
- #endif
- es(" entry elapsed: "); ehex(entry_dword);
- es(" elapsed: "); ehex(elapsed.dword);
- elapsed.word.hi++;
- VIA[vIER] = 0xC0;
- VIA[vT1C] = VIA[vT1CH] = ~0;
- #if 0 /* This always prints as f3, not c0! */
- es("new VIA[vIER]: "); ehex(VIA[vIER] & 0xff);
- #endif
- enl();
- }
- #endif
-
- #if 0 /* Hangs */
- ecnl(); es("VIA: "); ehex(elapsed.dword); enl();
- #endif
- return(elapsed.dword);
- }
-
- /*
- Compensate for a presumably missed rollover interrup.
- */
- long my_VIA_rollover(void);
- long
- my_VIA_rollover(void)
- {
- ++elapsed.word.hi;
- VIA[vT1C] = VIA[vT1CH] = ~0;
- return(elapsed.dword);
- }
-
- /*
- * start_VIA_timer
- *
- * It is not necessary to call this routine, as it is automatically
- * invoked by "VIA_ticks".
- *
- */
- void
- my_start_VIA_timer(int flag)
- {
- /* install rollover interrupt */
-
- /* This does *not* set the elapsed time. */
- VIA[vT1C] = VIA[vT1CH] = ~0;
-
- if (flag == FALSE) {
- save.vector = Lvl1DT[6];
- save.enable = VIA[vIER];
- }
- #if 0
- else {
- ecnl(); es("old vector: "); eptr(save.vector);
- es(" old enable: "); ehex(save.enable); enl();
- }
- #endif
- asm {
- lea @A5,a0
- move.l a5,(a0)
- lea @rollover,a0
- move.l a0,Lvl1DT[6]
- }
- VIA[vIER] = 0xC0;
-
- /* arrange for timer to be stopped at exit */
-
- timer_running = true;
- if (!exithook_installed) {
- _atexit(stop_VIA_timer);
- exithook_installed = true;
- }
- return;
-
- /* interrupt handler */
-
- rollover:
- /* Save register. */
- asm {
- move.l a5,-(sp)
- movea.l @A5,a5
- }
- ++elapsed.word.hi;
- VIA[vT1C] = VIA[vT1CH] = ~0;
- /* Restore register. */
- asm {
- movea.l (sp)+,a5
- rts
- A5: dc.l 0 ; store app's A5 here
- }
- }
-
-
- /*
- * stop_VIA_timer
- *
- * It is not necessary to call this routine, as it will be called
- * automatically at program exit.
- *
- */
-
- void
- stop_VIA_timer(void)
- {
- if (timer_running) {
- if (!(save.enable & 0x40))
- VIA[vIER] = 0x40;
- Lvl1DT[6] = save.vector;
- timer_running = false;
- }
- }
-